package cn.wolfcode.luowowo.serach.service.impl;

import cn.wolfcode.luowowo.search.query.SearchQueryObject;
import cn.wolfcode.luowowo.search.repository.IStrategyTemplateRepository;
import cn.wolfcode.luowowo.search.service.IStrategySearchService;
import cn.wolfcode.luowowo.search.template.StrategyTemplate;
import cn.wolfcode.luowowo.search.vo.StatisVo;
import com.alibaba.dubbo.config.annotation.Service;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.composite.CompositeAggregation;
import org.elasticsearch.search.aggregations.bucket.composite.CompositeAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.composite.CompositeValuesSourceBuilder;
import org.elasticsearch.search.aggregations.bucket.composite.TermsValuesSourceBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;

import java.util.*;

@Service
public class StrategySearchServiceImpl implements IStrategySearchService {

    @Autowired
    private IStrategyTemplateRepository dao;

    @Autowired
    private ElasticsearchTemplate template;

    @Autowired
    private TransportClient client;

    public void createIndex(){
        template.createIndex(StrategyTemplate.class);
        template.putMapping(StrategyTemplate.class);
    }

    public void save(StrategyTemplate template) {
        dao.save(template);
    }

    public List<StatisVo> queryStrategyCondition(int conditionType) {
        List<CompositeValuesSourceBuilder<?>> sources = new ArrayList<>();

        //拿到id
        TermsValuesSourceBuilder idSource = new TermsValuesSourceBuilder("id");
        idSource.missingBucket(true); //忽略不满足条件的bucket

        TermsValuesSourceBuilder nameSource = new TermsValuesSourceBuilder("name");
        nameSource.missingBucket(true); //忽略不满足条件的bucket
        //判断查中国还是查外国的判断条件
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //国内
        if(conditionType == SearchQueryObject.CONDITION_TYPE_UN_ABROAD ){
            idSource.field("provinceId"); //分组字段
            nameSource.field("provinceName"); //分组字段
            boolQuery.must(QueryBuilders.termQuery("countryId", 1));
        }else if(conditionType == SearchQueryObject.CONDITION_TYPE_ABROAD){
            idSource.field("countryId"); //分组字段
            nameSource.field("countryName"); //分组字段
            boolQuery.mustNot(QueryBuilders.termQuery("countryId", 1));
        }else if(conditionType == SearchQueryObject.CONDITION_TYPE_THEME){
            idSource.field("themeId"); //分组字段
            nameSource.field("themeName"); //分组字段
        }

        sources.add(idSource);
        sources.add(nameSource);

        CompositeAggregationBuilder builder = new CompositeAggregationBuilder("CountGroup",sources);
        //设置ES的索引
        SearchRequest request = new SearchRequest(StrategyTemplate.INDEX_NAME);
        request.types(StrategyTemplate.TYPE_NAME);
        request.source(new SearchSourceBuilder()
                .aggregation(builder)
                .query(boolQuery)
                .size(0));

        //发送get请求
        SearchResponse response = this.client.search(request).actionGet();
        //拿到了请求回来的结果
        Aggregations aggregations = response.getAggregations();
        CompositeAggregation compostieAggregation = aggregations.get("CountGroup");
        //结果封装
        List<? extends CompositeAggregation.Bucket> buckets = compostieAggregation.getBuckets();
        List<StatisVo> Vos = new ArrayList<>();
        //创建一个list用来去重
        List<StatisVo> name = new ArrayList<>();
        for (CompositeAggregation.Bucket bucket : buckets) {
            StatisVo vo = new StatisVo();
            Map<String, Object> key = bucket.getKey();
            vo.setId(Long.valueOf(key.get("id").toString()));
            vo.setName(key.get("name").toString());
            vo.setCount(bucket.getDocCount());
            Vos.add(vo);
        }
        //比较两边的值是否相等
        Collections.sort(Vos, new Comparator<StatisVo>() {
            public int compare(StatisVo o1, StatisVo o2) {
                return o2.getCount().compareTo(o1.getCount());
            }
        });
        return Vos;
    }

    public List<Map<String, Object>> queryThemeCommends() {

        List<CompositeValuesSourceBuilder<?>> sources = new ArrayList<>();

        //拿到id
        TermsValuesSourceBuilder idSource = new TermsValuesSourceBuilder("id");
        idSource.field("themeId");//分组字段
        idSource.missingBucket(true); //忽略不满足条件的bucket

        TermsValuesSourceBuilder nameSource = new TermsValuesSourceBuilder("name");
        nameSource.field("themeName");//分组字段
        nameSource.missingBucket(true); //忽略不满足条件的bucket

        sources.add(idSource);
        sources.add(nameSource);

        CompositeAggregationBuilder builder = new CompositeAggregationBuilder("themeGroup",sources);
        //设置ES的索引
        SearchRequest request = new SearchRequest(StrategyTemplate.INDEX_NAME);
        request.types(StrategyTemplate.TYPE_NAME);
        request.source(new SearchSourceBuilder()
                .aggregation(builder)
                .size(0));

        //发送get请求
        SearchResponse response = this.client.search(request).actionGet();
        //拿到了请求回来的结果
        Aggregations aggregations = response.getAggregations();
        CompositeAggregation compostieAggregation = aggregations.get("themeGroup");
        //结果封装
        List<? extends CompositeAggregation.Bucket> buckets = compostieAggregation.getBuckets();
        List<StatisVo> themesVos = new ArrayList<>();
        //创建一个list用来去重
        List<StatisVo> name = new ArrayList<>();
        for (CompositeAggregation.Bucket bucket : buckets) {
            StatisVo vo = new StatisVo();
            Map<String, Object> key = bucket.getKey();
            vo.setId(Long.valueOf(key.get("id").toString()));
            vo.setName(key.get("name").toString());
            vo.setCount(bucket.getDocCount());
            themesVos.add(vo);
        }
        //比较两边的值是否相等
        Collections.sort(themesVos, new Comparator<StatisVo>() {
            public int compare(StatisVo o1, StatisVo o2) {
                return o2.getCount().compareTo(o1.getCount());
            }
        });
        //只要前10个
        if(themesVos.size()>10){
            themesVos.subList(0, 10);
        }
        //外层的List
        List<Map<String, Object>> data = new ArrayList<>();

        //内层的
        Map<String,Object> map ;
        for (StatisVo themesVo : themesVos) {
            List<StatisVo> list = queryDestByThemeId(themesVo.getId());
            map = new HashMap<>();
            map.put("theme",themesVo);
            map.put("dests", list);
            data.add(map);

        }
        return data;
    }

    private List<StatisVo> queryDestByThemeId(Long themeId) {
        List<StatisVo> list = new ArrayList<>();

        Iterable<StrategyTemplate> iterable = dao.search(QueryBuilders.termQuery("themeId", themeId));
        //name排除去重
        List<String> name = new ArrayList<>();
        iterable.forEach(s ->{
            if (!name.contains(s.getDestName())) {
                StatisVo Vo = new StatisVo();
                Vo.setId(s.getDestId());
                Vo.setName(s.getDestName());
                list.add(Vo);
                name.add(s.getDestName());
            }
        });
        return list;
        }

    public Page<StrategyTemplate> queryDestById(SearchQueryObject qo) {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        if(qo.getDestId()!= -1){
            boolQuery.must(QueryBuilders.termQuery("destId", qo.getDestId()));
        }
        return dao.search(boolQuery, qo.getPageableWithoutSort());
    }

    public Page<StrategyTemplate> query(SearchQueryObject qo) {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //如果类型为国外的话
        if(qo.getType() == SearchQueryObject.CONDITION_TYPE_ABROAD){
            boolQuery.must(QueryBuilders.termQuery("countryId", qo.getTypeValue()));
            //如果是国内的话
        }else if(qo.getType() == SearchQueryObject.CONDITION_TYPE_UN_ABROAD){
            boolQuery.must(QueryBuilders.termQuery("provinceId", qo.getTypeValue()));
            //如果是主题
        }else if(qo.getType() == SearchQueryObject.CONDITION_TYPE_THEME){
            boolQuery.must(QueryBuilders.termQuery("themeId", qo.getTypeValue()));
        }
        Page<StrategyTemplate> page = dao.search(boolQuery, qo.getPageable());
        return page;
    }
}
